home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1996 / MacHack 1996.toast / Hacks / Hacks ’92 / The Essential Hack / Simply Essential.a < prev   
Encoding:
Text File  |  1992-06-16  |  10.9 KB  |  546 lines  |  [TEXT/MPS ]

  1.         CASE    OBJECT
  2.         STRING    ASIS
  3.         
  4.         PRINT    PUSH
  5.         PRINT    OFF
  6.  
  7. ; Allan and Scott wrote this one day in June, not long before MacHack ’92
  8. ;
  9. ;
  10. ;    This version, Allan modified so that it uses a simple install.
  11. ;    This version cannot be uninstalled, and does not allocate and memory.
  12. ;    Note the DetachResource call in the installer.... <grin>
  13. ;    otherwise bad and evil things can happen, when the resource is relesaed!
  14. ;
  15. ;
  16.  
  17. ;Include only the minimum necessary!
  18.  
  19.         INCLUDE    'Traps.a'
  20. wholeQuick    EQU    1
  21.         INCLUDE    'QuickEqu.a'
  22. wholeSystem    EQU 1
  23.         INCLUDE    'SysEqu.a'
  24. wholeTools    EQU    0
  25.         INCLUDE    'ToolEqu.a'
  26.         INCLUDE    'PackMacs.a'
  27.  
  28.  
  29.         PRINT    POP
  30.         
  31. WayBadValue    equ    $50FF8001                    ; An evil value to init to Bus Error
  32.  
  33. ;----------
  34.  
  35.         SEG        'Essential'
  36.         PROC
  37. StartOfCode
  38.         _Debugger
  39.         Bsr        Essential                    ; Install Ourselves
  40.         move.L    EndOfPatches-StartOfCode,D0
  41.         _SethandleSize                        ; Remove the install code
  42.         RTS                                    ; And return
  43.         DC.B     'MaChAcK'
  44.         
  45.         Align    2
  46.  
  47. ;----------
  48.  
  49.  
  50. ;This block contains the patches.
  51.  
  52. PatchNewHandle
  53.         Move.l    A0,-(sp)
  54.         Lea        NewHandleCounter,A0
  55.         Add.l    #1,(a0)
  56.         Move.l    (SP)+,A0
  57.         Move.l    OldNewHandle,-(sp)
  58.         Rts
  59. OldNewHandle
  60.         DC.L    WayBadValue
  61.  
  62. PatchDisposeHandle
  63.         Move.l    A0,-(sp)
  64.         Lea        DisposeHandleCounter,A0
  65.         Add.l    #1,(a0)
  66.         Move.l    (SP)+,A0
  67.         Move.l    OldDisposeHandle,-(sp)
  68.         Rts
  69. OldDisposeHandle
  70.         DC.L    WayBadValue
  71.  
  72.  
  73. PatchNewPtr
  74.         Move.l    A0,-(sp)
  75.         Lea        NewPtrCounter,A0
  76.         Add.l    #1,(a0)
  77.         Move.l    (SP)+,A0
  78.         Move.l    OldNewPtr,-(sp)
  79.         Rts
  80. OldNewPtr
  81.         DC.L    WayBadValue
  82.  
  83.  
  84. PatchDisposePtr
  85.         Move.l    A0,-(sp)
  86.         Lea        DisposePtrCounter,A0
  87.         Add.l    #1,(a0)
  88.         Move.l    (SP)+,A0
  89.         Move.l    OldDisposePtr,-(sp)
  90.         Rts
  91. OldDisposePtr
  92.         DC.L    WayBadValue
  93.  
  94. PatchRead
  95.         Move.l    A0,-(sp)
  96.         Lea        ReadCounter,A0
  97.         Add.l    #1,(a0)
  98.         Move.W    inLoadSeg,D0
  99.         Beq.S        @1
  100.         Lea        LoadSegHitDisk,A0
  101.         Add.L    #1,(A0)
  102. @1        Move.W    inGetResource,D0
  103.         Beq.S        @2
  104.         Lea        GetResourceHitDisk,A0
  105.         Add.L    #1,(A0)
  106. @2        Move.l    (SP)+,A0
  107.         Move.l    OldRead,-(sp)
  108.         Rts
  109. OldRead
  110.         DC.L    WayBadValue
  111.  
  112. PatchWrite
  113.         Move.l    A0,-(sp)
  114.         Lea        WriteCounter,A0
  115.         Add.l    #1,(a0)
  116.         Move.l    (SP)+,A0
  117.         Move.l    OldWrite,-(sp)
  118.         Rts
  119. OldWrite
  120.         DC.L    WayBadValue
  121.  
  122. PatchLoadSeg
  123.         Move.l    A0,-(sp)
  124.         Lea        LoadSegCounter,A0
  125.         Add.l    #1,(a0)
  126.         Lea        inLoadSeg,A0
  127.         Move.w    #1,(A0)
  128.         Move.l    (SP)+,A0
  129.         Move.l    OldLoadSeg,-(sp)
  130.         Rts
  131. OldLoadSeg
  132.         DC.L    WayBadValue
  133.  
  134. GetResourceFrame    RECORD    {Link},Decr
  135. Result        DS.L    1                        ; Stack frome for GetResource
  136. Type        DS.L    1
  137. ID            DS.W    1                            
  138. Return        DS.L    1
  139. Link        DS.L    1
  140. FrameSZ        EQU        *-Link
  141.             ENDR
  142.  
  143. PatchGetResource
  144.         With    GetResourceFrame
  145.         Link    A6,#FrameSZ
  146.         Move.l    A0,-(sp)
  147.         Lea        GetResourceCounter,A0
  148.         Add.l    #1,(a0)
  149.         Lea        inGetResource,A0
  150.         Move.w    #1,(A0)
  151.         Move.l    (SP)+,A0
  152.  
  153.         Move.L    Result(a6),-(sp)                ; Move the result value...
  154.         Move.L    Type(a6),-(sp)                    ; and the type
  155.         Move.W    ID(a6),-(sp)                    ; and the ID
  156.         
  157.         Pea        MyTailPatch                        ; The place for us to return to
  158.         Move.l    OldGetResource,-(sp)
  159.         Rts                                        ; Do Scott’s Really cool Jump with No registers Blown
  160.         
  161. MyTailPatch
  162.         Move.L    A0,-(SP)
  163.         
  164.         Lea        inGetResource,A0
  165.         Clr.W    (A0)                            ; OK, So now we are back, and we can clean up
  166.         Lea        inLoadSeg,A0
  167.         Clr.W    (A0)
  168.         
  169.         Move.L    (SP)+,A0
  170.         
  171.         Move.L    (SP)+,Result(a6)
  172.         Unlk    A6
  173.         Move.L    (SP),6(SP)                        ; Put the return address up the stack,
  174.         Add        #6,SP                            ; and clean up the stack
  175.         RTS
  176.         
  177.         EndWith 
  178.         
  179. OldGetResource
  180.         DC.L    WayBadValue
  181.  
  182. ;  ••••••••••••••••••••••• T H I S   I S    S C O T T ' S    C O D E ••••••••••••••••••••••
  183.  
  184. redrawInterval    equ    60
  185.  
  186. PatchGNEFilter
  187.  
  188.         MOVEM.L    D0-D2/A0-A1,-(SP)
  189.  
  190.         move.l    evtTicks(A1),D1                ; tickCount as of now
  191.         move.l    GNEFilterTimer,D2            ; tickCount at last update
  192.         sub.l    D2,D1                        ; ticks since last update
  193.         cmp.l    #redrawInterval,D1
  194.         blt.s    @Done                        ; branch if elapsed < redrawInterval
  195.         Lea        GNEFilterTimer,A0
  196.         move.l    evtTicks(a1),(a0)            ; remember the time
  197.  
  198.         Clr.W    -(SP)
  199.         _FlashMenuBar
  200.         Lea        DebugFlag,A0
  201.         Tst.W    (A0)
  202.         Beq.S    @Done
  203.         _Debugger
  204.         Bsr.S    ClearTheDataBlock
  205.         
  206. @Done    Movem.L    (SP)+,D0-D2/A0-A1
  207.         Move.l    OldGNEFilter,-(sp)
  208.         Rts
  209.  
  210. OldGNEFilter
  211.         DC.L    WayBadValue
  212. GNEFilterTimer
  213.         DC.L    0
  214.  
  215.         
  216. ;     This is the routine called by Gestalt to return the Proc Pointer.
  217. ;
  218. ;    OSErr gestaltSelectorProc(OSType selector,long *response);
  219. ;
  220. ;    Since this is called from Gestalt, we do not have to save any registers
  221.  
  222. ReturnTheGestaltHandlerProc
  223.         
  224.         Lea        GestaltHandlerProc,A1
  225.         Move.w    #0,$0a(Sp)                        ; No Error ocurred here!
  226.         Move.l    4(SP),A0
  227.         Move.l    A1,(A0)                            ; put the result into the right place....
  228.         Move.L    (SP)+,8(Sp)                        ; Get the return address
  229.         Addq.w    #8,A7                            ; Lose the args
  230.         Rts                                        ; And return
  231. Hey, why is this different?
  232.  
  233.  
  234. ReturnDataBlock
  235.         Lea        NewHandleCounter,A1
  236.         Rts
  237.  
  238. ;
  239. ;        This Function clears the counters, and updates the running totals...
  240. ;
  241.  
  242. ClearTheDataBlock
  243.         Lea        NewHandleCounter,A0
  244.         move.L    (A0),D0
  245.         Add.L    D0,4(A0)
  246.         Clr.L    (A0)
  247.         Lea        DisposeHandleCounter,A0
  248.         move.L    (A0),D0
  249.         Add.L    D0,4(A0)
  250.         Clr.L    (A0)
  251.         Lea        NewPtrCounter,A0
  252.         move.L    (A0),D0
  253.         Add.L    D0,4(A0)
  254.         Clr.L    (A0)
  255.         Lea        DisposePtrCounter,A0
  256.         move.L    (A0),D0
  257.         Add.L    D0,4(A0)
  258.         Clr.L    (A0)
  259.         Lea        ReadCounter    ,A0
  260.         move.L    (A0),D0
  261.         Add.L    D0,4(A0)
  262.         Clr.L    (A0)
  263.         Lea        WriteCounter,A0
  264.         move.L    (A0),D0
  265.         Add.L    D0,4(A0)
  266.         Clr.L    (A0)
  267.         Lea        LoadSegCounter,A0
  268.         move.L    (A0),D0
  269.         Add.L    D0,4(A0)
  270.         Clr.L    (A0)
  271.         Lea        LoadSegHitDisk,A0
  272.         move.L    (A0),D0
  273.         Add.L    D0,4(A0)
  274.         Clr.L    (A0)
  275.         Lea        GetResourceCounter,A0
  276.         move.L    (A0),D0
  277.         Add.L    D0,4(A0)
  278.         Clr.L    (A0)
  279.         Lea        GetResourceHitDisk,A0
  280.         move.L    (A0),D0
  281.         Add.L    D0,4(A0)
  282.         Clr.L    (A0)
  283.         Move.l    #0,A1
  284.  
  285.         Rts
  286.         
  287. UninstallRoutine
  288.         Move.l    #0,A1                            ; Just return Null
  289.         Rts
  290.         
  291.         
  292. ;    Define a routine actually does the gestalt things....
  293. ;    Has the following interface.
  294. ;
  295. ;    Defined using Pascal syntax, since we may want to call it from there!
  296. ;
  297. ;    long GestaltHandlerProc(short selector, char *param);
  298. ;
  299.  
  300. sTablePointer    equ        0
  301. sClearTable        equ        1
  302. sUninstall        equ        2
  303.  
  304.  
  305. GestaltHandlerFrame    RECORD    {Link},Decr
  306. Result        DS.L    1                        ; Stack frome for GestaltHandlerProc
  307. selector    DS.W    1
  308. param        DS.L    1                            
  309. Return        DS.L    1
  310. Link        DS.L    1
  311. FrameSZ        EQU        *-Link
  312.             ENDR
  313.  
  314. GestaltHandlerProc
  315.         With        GestaltHandlerFrame
  316.         Link        A6,#FrameSZ                    ; No need for locals here
  317.         Movem.l        A0-A2/D0-D2,-(SP)            ; save some registers
  318.         Move.W        selector(A6),D0
  319.         Move.L        param(A6),A1
  320.         Asl.W        #2,D0                        ; multiply by 4
  321.         Lea            myJumpTable,A0
  322.         Move.W        (A0,D0.W),D0                ; index to find the right code...
  323.         Jsr            (A0,D0.W)                    ; and do the thing....
  324.         move.l        A1,Result(A6)                ; and put the result back
  325.         Unlk        A6
  326.         Movem.l        (SP)+,A0-A2/D0-D2            ; restore the registers
  327.         Move.L        (SP),$6(A6)                    ; Move the return address up....
  328.         Addq        #6,SP                        ; clean up the stack
  329.         Rts
  330.         EndWith
  331.  
  332. ;    Set up our jumptable.
  333. ;    All these values should be negative, since they are before this!
  334. ;
  335.  
  336. myJumpTable    
  337.  
  338.         DC.W        ReturnDataBlock - myJumpTable
  339.         DC.W        ClearTheDataBlock - myJumpTable
  340.         DC.W        UninstallRoutine - myJumpTable
  341.         DC.W        0
  342.  
  343.         Align    2
  344.         
  345. PatchPtr                DC.L    0
  346. DebugFlag                DC.W    1
  347. didARead                DC.W    0
  348. inGetResource            DC.W    0
  349. inLoadSeg                DC.W    0
  350.  
  351. ;        The table is kept as two longs,  The first is the count,
  352. ;        which is reset every time, and the second is a running total, Never reset.
  353.  
  354. TheDataBlock
  355.  
  356. NewHandleCounter        DC.L    0,0
  357. DisposeHandleCounter    DC.L    0,0
  358. NewPtrCounter            DC.L    0,0
  359. DisposePtrCounter        DC.L    0,0
  360. ReadCounter                DC.L    0,0
  361. WriteCounter            DC.L    0,0
  362. LoadSegCounter            DC.L    0,0
  363. LoadSegHitDisk            DC.L    0,0
  364. GetResourceCounter        DC.L    0,0
  365. GetResourceHitDisk        DC.L    0,0
  366.  
  367. EndOfTheList            DC.L    -1,-1,-1,-1        ; just a sentiel value, so we can easily see the list
  368.                                                 ; when debugging!  (Which is never needed!)
  369.  
  370.  
  371. ;----------
  372. EndOfPatches
  373.  
  374. ;----------
  375.  
  376. Credits
  377.         DC.B    'AppleLink addresses:  Allan & Scott'
  378.         
  379.         ALIGN     2
  380. Essential
  381.  
  382. ;Set up here.
  383.  
  384. ; Typically, you should mark your INIT resource as Preload & Locked.
  385. ; This gets it in the "application" heap nice and early and nice and low.
  386. ; Because we are going to do that, we’re not going to waste code to
  387. ; do what the resource manager is happy to do for us.
  388.  
  389.         lea    StartOfCode,a0
  390.         _RecoverHandle
  391.         _HLock                        ; just lock me down in case...
  392.         Move.L    A0,-(SP)
  393.         _DetachResource                ;    Since we are going to leave it lying around...
  394.  
  395. ShiftMask    equ    0
  396.  
  397. ; Do the polite thing, and don’t load if the user doesn’t want us.
  398.         Lea        KeyMap,a0
  399.         BTST     #ShiftMask,7(a0)
  400.         BNZ        BailOut
  401.  
  402. NewHandle        equ    $A122
  403. DisposeHandle    equ    $A023
  404. NewPtr            equ    $A11E
  405. DisposePtr        equ    $A01F
  406. Read            equ    $A002
  407. Write            equ    $A003
  408. LoadSeg            equ $A9F0
  409. GetResource        equ    $A9A0
  410.  
  411. ;    jGNEFilter        equ 666                ; You decide…
  412.  
  413. ;Set up the patches-to-be.
  414.  
  415.         LEA        OldGNEFilter,A0
  416.         move.l    jGNEFilter,(A0)        ; save off the old jGNEFilter
  417.  
  418.         MOVE.W    #NewHandle,D0
  419.         _GetTrapAddress newOS
  420.         LEA    OldNewHandle,A1
  421.         MOVE.L    A0,(A1)
  422.         
  423.         MOVE.W    #DisposeHandle,D0
  424.         _GetTrapAddress newOS
  425.         LEA    OldDisposeHandle,A1
  426.         MOVE.L    A0,(A1)
  427.  
  428.         MOVE.W    #NewPtr,D0
  429.         _GetTrapAddress newOS
  430.         LEA    OldNewPtr,A1
  431.         MOVE.L    A0,(A1)
  432.  
  433.         MOVE.W    #DisposePtr,D0
  434.         _GetTrapAddress newOS
  435.         LEA    OldDisposePtr,A1
  436.         MOVE.L    A0,(A1)
  437.  
  438.         MOVE.W    #Read,D0
  439.         _GetTrapAddress newOS
  440.         LEA    OldRead,A1
  441.         MOVE.L    A0,(A1)
  442.  
  443.         MOVE.W    #Write,D0
  444.         _GetTrapAddress newOS
  445.         LEA    OldWrite,A1
  446.         MOVE.L    A0,(A1)
  447.  
  448.         MOVE.W    #LoadSeg,D0
  449.         _GetTrapAddress newTool
  450.         LEA    OldLoadSeg,A1
  451.         MOVE.L    A0,(A1)
  452.  
  453.         MOVE.W    #GetResource,D0
  454.         _GetTrapAddress newTool
  455.         LEA    OldGetResource,A1
  456.         MOVE.L    A0,(A1)
  457.  
  458.  
  459. InstallPatches
  460.  
  461.          move.l    PatchPtr,a1
  462.  
  463.         LEA        PatchGNEFilter,A0                    ; somebody’s got to get the utility check!
  464.         Move.L    A0,jGNEFilter                        ; to get some time, patch us into jGNEFilter (GetNextEvent)
  465.  
  466.         Lea        PatchNewHandle,A0
  467.         MOVE.W    #NewHandle,D0
  468.         _SetTrapAddress newOS
  469.  
  470.         Lea        PatchDisposeHandle,A0
  471.         MOVE.W    #DisposeHandle,D0
  472.         _SetTrapAddress newOS
  473.  
  474.         Lea        PatchNewPtr,A0
  475.         MOVE.W    #NewPtr,D0
  476.         _SetTrapAddress newOS
  477.  
  478.         Lea        PatchDisposePtr,A0
  479.         MOVE.W    #DisposePtr,D0
  480.         _SetTrapAddress newOS
  481.  
  482.         Lea        PatchRead,A0
  483.         MOVE.W    #Read,D0
  484.         _SetTrapAddress newOS
  485.  
  486.         Lea        PatchWrite,A0
  487.         MOVE.W    #Write,D0
  488.         _SetTrapAddress newOS
  489.  
  490.         Lea        PatchLoadSeg,A0
  491.         MOVE.W    #LoadSeg,D0
  492.         _SetTrapAddress newTool
  493.  
  494.         Lea        PatchGetResource,A0
  495.         MOVE.W    #GetResource,D0
  496.         _SetTrapAddress newTool
  497.         
  498.         lea        ReturnTheGestaltHandlerProc,A0
  499.         Move.L    #'Sntl',D0
  500.         _NewGestalt                                ;    If it fails, then something bad happened...
  501.                                                 ;    but nothing we can do about it now
  502.  
  503.  
  504.         bra.s    loaded
  505.         
  506. ;Common exit-point.
  507. BailOut
  508. ;        
  509. ;        PROCEDURE ShowINIT(iconID: Integer; moveX: Integer);
  510.         IMPORT    SHOWINIT:CODE        
  511.  
  512. didntLoadIconID    equ    -4063        
  513. patchLoadedIconID    equ    -4064        
  514.  
  515.         move.w    #didntLoadIconID,-(a7)            ; Shift held -- Didn’t load
  516.         bra.s    ShowIt
  517.  
  518.         
  519. loaded    move.w    #patchLoadedIconID,-(a7)    ; OK Show the ICON and go
  520. ShowIt    move.w    #-1,-(a7)
  521.         Bsr        SHOWINIT
  522.  
  523. exit    RTS
  524.  
  525. ; What happens to this locked block, you ask?  Easy, the heap is about to
  526. ; get blown away, so we really don’t have to do anything to tidy up.
  527.  
  528.         END
  529.  
  530.  
  531. ••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
  532. AOptions    =    -case on
  533.  
  534.  
  535. Essential    ƒ    Essential.rsrc Essential.a.o
  536.     Duplicate -y Essential.rsrc {Targ}
  537.     Link -o {Targ} -rt INIT=-4064 -sg Essential -ra =resLocked ∂
  538.                                                 Essential.a.o ∂
  539.                                                 {libraries}ShowInit.a.o
  540.     SetFile -t INIT -c 'APF2' {Targ}
  541.  
  542. Essential.rsrc ƒ Essential.r
  543.     Rez -o {Targ} Essential.r
  544.     
  545.     
  546.